# @Time : 2024-10-25 16:13
# @Author : Fioman 
# @Phone : 13149920693
"""
__getattr__: 属性访问,仅仅是在属性不存在的时候被调用
__getattribute__: 对任何属性访问都会调用它,优先级高于__getattr__
"""


# region 1. __getattr__ 访问不存在属性时返回默认值触发错误或者执行其它逻辑
class MyClass:
    def __init__(self):
        self.exsitAttribute = "I Exist"

    def __getattr__(self, attrName):
        # 当属性不存在时返回下面的内容
        return f"{attrName} 属性不存在"


obj = MyClass()
print(obj.exsitAttribute)
print(obj.notExsitAttribute)


# endregion

# region 2. __getattribute__ 对每一个属性访问都会调用的一个方法,不管该属性是否存在.调用父类
# 主要用途,控制素有属性访问,统一访问逻辑, 日志记录,属性访问权限控制
class Person:
    def __init__(self, name):
        self.name = name

    def __getattribute__(self, item):
        print(f"Accessing __getattribute__: {item}")


obj = Person("Fioman")  # 这里没有属性访问
obj.name = 123  # 这里不是访问,这里是设置
print(obj.name)  # 访问name 存在的属性


# endregion

# region 3. 综合案例  __getattr__  __getattribute__一起使用
class Simple:
    def __init__(self):
        self.exsitAttribute = "I Exist"

    def __getattribute__(self, attrName):
        print(f"Accessing __getattribute__: {attrName}")
        return super().__getattribute__(attrName)
        # 使用super() 调用原有的__getattribute__防止无限递归
        # try:
        #     return super().__getattribute__(attrName)
        # except AttributeError:
        #     return self.__getattr__(attrName)

    def __getattr__(self, attrName):
        return f"{attrName} not found"


simple = Simple()
print(simple)
print(simple.exsitAttribute)
print(simple.notExsitAttribute)

# endregion
